
#pragma once

#include "UfPacket.h"
#include "UfTimeout.h"
#include "UfFile.h"
#include "tools/socket.h"

#include <list>

class UfServerNode : public UfTimeout
{
public:
    UfServerNode(tools::CSocket& sock);
    void parsePacket(const char * buffer, int len);

    bool isValid() { return mValid; }
    int  sid() { return mSid; }

    int  makeSid();

    void Send(UfPacket& packet);

    void onWritable();

private:
    int     mSid;
    char    remoteIp[100];
    int     remotePort;
    bool    mValid;
    UfFile  mFile;
    tools::CSocket& mSock;

    class FilePart {
    public:
        __int64 offset;
        __int64 length;
        __int64 piecelength;
    };

    std::list<FilePart> mSendList;

private:
    enum {
        S_INIT = 0,
        S_HANDSHAKE,
        S_COMMAND,
    } mState;

    int mRetryTimes;
    int mClientPieceBuffer;
    __int64 mClientPieceLength;

    void Close();

    // 握手
    void onInit(UfPacket* packet);
    void onHandshake(UfPacket* packet);
    void toHello(void* arg);

    // 心跳
    void toHeartbit(void* arg);

    // 断线
    void toDisconnect(void* arg);

    // 命令
    void onCommand(const char * buffer, int len);

    // File
    void toSendFile(void* arg);

    // 等待SendOver的ack
    void toWaitingSendOverAck(void* arg);

};










